
#include "Block.h"

Block::Block( int block_x, int block_y, string block_img_name, char ascend_or_descend )
{
    // load the image
    block_img.load( block_img_name );

    this->ascend_or_descend = ascend_or_descend;

    // parse that string so i get just the file name
    int img_name_size = block_img_name.size();

    // move past the file exstension
    while ( '/' != block_img_name[ img_name_size ] )
        img_name_size--;

    // get the GOOD stuff
    int index = 0;
    while( '.' != block_img_name[ img_name_size + 1 ] )
    {
        char tmp = block_img_name[ img_name_size + 1 ];
        block_type += tmp;
        img_name_size++;
        index++;
    }

    // now that i have the file_name, give height and width a value
    Assign_width_height( block_type, ascend_or_descend, block_x, block_y );

} // class constructor

Block::~Block()
{

}

void Block::Assign_width_height( string block_type, char ascend_or_descend, int block_x, int block_y )
{
    // push the x and y coordinates then add the height and width later in Assign_width_height()
    SDL_Rect tmp;
    tmp.x = block_x;
    tmp.y = block_y;

    CONST_X_Y_vector.push_back( block_x ); // index 0
    CONST_X_Y_vector.push_back( block_y );


    // set the width and height
    if( 0 == block_type.compare( "grassblock" ) )
    {
        tmp.w = 160;
        tmp.h = 66;
        rect_location_vector.push_back( tmp );
        //cout << "grassblock pushed on list\n";
    }
    else if( 0 == block_type.compare( "house" ) )
    {
        tmp.w = 20;
        tmp.h = 200;
        rect_location_vector.push_back( tmp );
    }
    else if( 0 == block_type.compare( "hut" ) )
    {

    }
    else if( 0 == block_type.compare( "rockbg" ) )
    {
        cout << "rockbg created\n";
        tmp.w = 255; // single image == 85
        tmp.h = 200;
        rect_location_vector.push_back( tmp );
    }
    else if( 0 == block_type.compare( "grassblocksmall" ) )
    {
        tmp.w = 100;
        tmp.h = 54;
        rect_location_vector.push_back( tmp );
        //cout << "grassblocksmall pushed on list\n";
    }
    else if( 0 == block_type.compare( "2doorhouse" ) )
    {
        tmp.w = 20;
        tmp.h = 200;
        rect_location_vector.push_back( tmp );
    }
    else if( 0 == block_type.compare( "groundtower") )
    {
        tmp.w = 250; // this should always be true

        int iter1_x = CONST_X_Y_vector[ 0 ], // X
            iter1_y = CONST_X_Y_vector[ 1 ];

        if( 'A' == ascend_or_descend )
        {
            tmp.h = 60;
            rect_location_vector.push_back( tmp );

            tmp.x = iter1_x + tmp.w; // 140
            tmp.y = iter1_y - 100;
            tmp.h = 200;
            rect_location_vector.push_back( tmp );

            // two more on the X / Y list
            CONST_X_Y_vector.push_back( tmp.x );
            CONST_X_Y_vector.push_back( tmp.y );

            tmp.x = iter1_x + tmp.w * 2; // 240
            tmp.y = iter1_y - 200;
            tmp.h = 400;
            rect_location_vector.push_back( tmp );

             // two more on the X / Y list
            CONST_X_Y_vector.push_back( tmp.x );
            CONST_X_Y_vector.push_back( tmp.y );
            // should be six items on this list now

        }
        else if( 'D' == ascend_or_descend )
        {
            CONST_X_Y_vector.clear();

            tmp.y = iter1_y - 200;
            tmp.h = 400;
            rect_location_vector.push_back( tmp );

            CONST_X_Y_vector.push_back( tmp.x );
            CONST_X_Y_vector.push_back( tmp.y );

            tmp.x = iter1_x + tmp.w; //140
            tmp.y = iter1_y - 100;
            tmp.h = 200;
            rect_location_vector.push_back( tmp );

            CONST_X_Y_vector.push_back( tmp.x );
            CONST_X_Y_vector.push_back( tmp.y );

            tmp.x = iter1_x + tmp.w * 2; //240
            tmp.y = iter1_y;
            tmp.h = 60;
            rect_location_vector.push_back( tmp );

            CONST_X_Y_vector.push_back( tmp.x );
            CONST_X_Y_vector.push_back( tmp.y );
        }
        else
        {
            cout << "invalid ascend_or_desend\n";
        }
    }
} // Assign_width_heigth()

char Block::Left_right_top_bottom_collision( SDL_Rect player_sprite, SDL_Rect block )
{
    char result = '\0';

    if( (player_sprite.x + player_sprite.w) >= block.x && player_sprite.x <= (block.x + block.w) )
    {
        // check for the correct Y collisions
        if( (player_sprite.y == (block.y + block.h)) ) // ==
            result = 'B';
    }
    if( (player_sprite.x + player_sprite.w) >= block.x && (player_sprite.x <= (block.x + block.w) ) )
    {
        // check for the correct Y collisions
        if( ( (player_sprite.y + player_sprite.h) <= block.y) && (player_sprite.y >= ( block.y - player_sprite.h - 3 ) ) ) // - 3
            result = 'T';
    }
    if( player_sprite.x >= (block.x + block.w - 5) ) // >=
    {
        // check for the correct X collisions
        if( player_sprite.x <= (block.x + block.w) )
        {
            // check for the correct Y collisions
            if( (player_sprite.y <= (block.y + block.h)) && ((player_sprite.y + player_sprite.h) > block.y) )
                result = 'R';
        }
    }
    if( (player_sprite.x + player_sprite.w) <= block.x + 5 ) //(player_sprite.x <= block.x
    {
        if( (player_sprite.x + player_sprite.w) >= block.x )
        {
            if( (player_sprite.y <= (block.y + block.h)) && ((player_sprite.y + player_sprite.h) > block.y) )
                result = 'L';
        }
    }

    return result;


} // Left_right_top_bottom_collision()

void Block::Detect_bullet_block_collision( Bullets_control &bullets )
{
    if( 0 == block_type.compare( "groundtower") )
    {
        list< Bullet * >::iterator bullet_iter0 = bullets.Get_bullets_control_begin();

        while( bullet_iter0 != bullets.Get_bullets_control_end() )
        {
            SDL_Rect bullet_sprite = (*bullet_iter0)->Get_bullet_loc();

            if( (bullet_sprite.x + bullet_sprite.w) >= rect_location_vector[0].x - 5
                && (bullet_sprite.x <= (rect_location_vector[2].x + rect_location_vector[2].w + 5) ) )
            {
                char tower0 = Left_right_top_bottom_collision( rect_location_vector[0], bullet_sprite ),
                    tower1 = Left_right_top_bottom_collision( rect_location_vector[1], bullet_sprite ),
                    tower2 = Left_right_top_bottom_collision( rect_location_vector[2], bullet_sprite );

                if( '\0' != tower0 )
                    bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );
                if( '\0' != tower1 )
                    bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );
                if( '\0' != tower2 )
                    bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );

                if( '\0' == tower0
                    && '\0' == tower1
                    && '\0' == tower2 )
                {
                    bullet_iter0++;
                }
            }
            else
                bullet_iter0++;
        }
    }
    else
    {
        list< Bullet * >::iterator bullet_iter0 = bullets.Get_bullets_control_begin();
        //int number = 0;

        while( bullet_iter0 != bullets.Get_bullets_control_end() )
        {
            //cout << "number: " << number << endl;
            //cout << "bullet block collision\n";
            SDL_Rect bullet_sprite = (*bullet_iter0)->Get_bullet_loc();
            SDL_Rect block = rect_location_vector[0];

            if( (bullet_sprite.x + bullet_sprite.w) >= block.x - 5 && (bullet_sprite.x <= (block.x + block.w + 5) ) )
            {
                //cout << "inside if in bullet collision\n";
                char left_right_top_bottom = Left_right_top_bottom_collision( bullet_sprite, block );

                switch( left_right_top_bottom )
                {
                    case 'L':
                        bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );
                        break;
                    case 'R':
                        bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );
                        break;
                    default:
                        bullet_iter0++;
                        break;
                }

            }
            else
                bullet_iter0++;
            //number++;
        } // while

    } // else
} // Detect_bullet_block_collision( Bullets_control &bullets )

void Block::Detect_block_collision( Player &current_player, Levels *current_level )
{
    SDL_Rect player_sprite = current_player.Get_sprite_info();

    if( 0 == block_type.compare( "groundtower") )
    {
        char tower0 = Left_right_top_bottom_collision( player_sprite, rect_location_vector[0] ),
            tower1 = Left_right_top_bottom_collision( player_sprite, rect_location_vector[1] ),
            tower2 = Left_right_top_bottom_collision( player_sprite, rect_location_vector[2] );

        // is the player close enough to start checking for collisions
        if( (player_sprite.x + player_sprite.w) >= rect_location_vector[0].x - 5 && (player_sprite.x <= (rect_location_vector[2].x + rect_location_vector[2].w + 5) ) )
        {
            current_player.Set_on_block( false );

            if( 'A' == ascend_or_descend )
            {
                if( 'L' == tower0 )
                {
                    current_level->Set_scrolling_right( false );
                }
                else if( 'T' == tower0 )
                {
                    current_player.Set_landed( true );
                    current_player.Set_on_block( true );
                    current_player.Set_jumping( false );
                    current_level->Reset_jump_spd();
                    current_level->Set_player_main_floor_y( rect_location_vector[0].y - player_sprite.h );
                }

                if( 'L' == tower1 )
                {
                    current_level->Set_scrolling_right( false );
                }
                else if( 'T' == tower1 )
                {
                    current_player.Set_landed( true );
                    current_player.Set_on_block( true );
                    current_player.Set_jumping( false );
                    current_level->Reset_jump_spd();
                    current_level->Set_player_main_floor_y( rect_location_vector[1].y - player_sprite.h );
                }

                if( 'L' == tower2 )
                {
                    current_level->Set_scrolling_right( false );
                }
                else if( 'T' == tower2 )
                {
                    current_player.Set_landed( true );
                    current_player.Set_on_block( true );
                    current_player.Set_jumping( false );
                    current_level->Reset_jump_spd();
                    current_level->Set_player_main_floor_y( rect_location_vector[2].y - player_sprite.h );
                }

                if( 'R' == tower2 )
                {
                    current_level->Set_scrolling_right( true );
                }
            }
            else if( 'D' == ascend_or_descend )
            {
                // descending tower
                if( 'L' == tower0 )
                {
                    current_level->Set_scrolling_right( false );
                }

                if( 'T' == tower0 )
                {
                    current_player.Set_landed( true );
                    current_player.Set_on_block( true );
                    current_player.Set_jumping( false );
                    current_level->Reset_jump_spd();
                    current_level->Set_player_main_floor_y( rect_location_vector[0].y - player_sprite.h );
                }
                else if( 'R' == tower0 )
                {
                    current_level->Set_scrolling_right( true );
                }

                if( 'T' == tower1 )
                {
                    current_player.Set_landed( true );
                    current_player.Set_on_block( true );
                    current_player.Set_jumping( false );
                    current_level->Reset_jump_spd();
                    current_level->Set_player_main_floor_y( rect_location_vector[1].y - player_sprite.h );
                }
                else if( 'R' == tower1 )
                {
                    current_level->Set_scrolling_right( true );
                }

                if( 'T' == tower2 )
                {
                    current_player.Set_landed( true );
                    current_player.Set_on_block( true );
                    current_player.Set_jumping( false );
                    current_level->Reset_jump_spd();
                    current_level->Set_player_main_floor_y( rect_location_vector[2].y - player_sprite.h );
                }
                else if( 'R' == tower2 )
                {
                    current_level->Set_scrolling_right( true );
                }
            }
        } // if the player close enough to start checking for collisions
    }
    else if( 0 == block_type.compare( "rockbg" ) )
    {
        SDL_Rect block = rect_location_vector[0];

        char left_right_top_bottom = Left_right_top_bottom_collision( player_sprite, block );
        if( 'T' == left_right_top_bottom )
        {
            current_player.Set_player_sinking( true );
        }
        // this is a copy of the 'B' from left_right_top_bottom_collision() with an altered inner if statement
        if( (player_sprite.x + player_sprite.w) >= block.x && player_sprite.x <= (block.x + block.w) )
        {
            // check for the correct Y collisions
            if( (player_sprite.y >= (block.y + block.h)) ) // ==
                current_level->Restart_level();
        }
    }
    else
    {
        SDL_Rect block = rect_location_vector[0];

        if( (player_sprite.x + player_sprite.w) >= block.x - 5 && (player_sprite.x <= (block.x + block.w + 5) ) )
        {
            char left_right_top_bottom = Left_right_top_bottom_collision( player_sprite, block );
            switch( left_right_top_bottom )
            {
                case 'L':
                    current_level->Set_scrolling_right( false );
                    break;
                case 'R':
                    current_level->Set_scrolling_right( true );
                    break;
                case 'T':
                    current_player.Set_landed( true );
                    current_player.Set_on_block( true );
                    current_player.Set_jumping( false );
                    current_level->Reset_jump_spd();
                    current_level->Set_player_main_floor_y( block.y - player_sprite.h );
                    break;
                case 'B':
                    current_player.Set_jumping( false );
                    break;
                default:
                    current_player.Set_on_block( false );
                    break;

            }
        }
    } // else
}//Detect_block_collision( Player &current_player, Levels *current_level )

void Block::Detect_block_collision( Enemy_control &enemys )
{
    //SDL_Rect player_sprite = current_player.Get_sprite_info();
    vector< Enemy >::iterator iter0 = enemys.Get_enemy_control_begin();

    while( iter0 != enemys.Get_enemy_control_end() )
    {
        //cout << "loop for enemy block collision\n";
        SDL_Rect enemy_sprite = (*(iter0)).Get_sprite_info();

        if( 0 == block_type.compare( "groundtower") )
        {
            char tower0 = Left_right_top_bottom_collision( enemy_sprite, rect_location_vector[0] ),
                tower1 = Left_right_top_bottom_collision( enemy_sprite, rect_location_vector[1] ),
                tower2 = Left_right_top_bottom_collision( enemy_sprite, rect_location_vector[2] );
//
//            cout << "tower0: " << tower0 << endl;
            // is the enemy close enough to start checking for collisions
            if( (enemy_sprite.x + enemy_sprite.w) >= rect_location_vector[0].x - 5 && (enemy_sprite.x <= (rect_location_vector[2].x + rect_location_vector[2].w + 5) ) )
            {
                //current_player.Set_on_block( false );
                if( 'A' == ascend_or_descend )
                {
                    (*iter0).Set_on_block( false );

                    if( 'L' == tower0 )
                    {
                        (*iter0).Set_moving_right( false );
                        (*iter0).Jump();
                    }
                    else if( 'T' == tower0 )
                    {
                        (*iter0).Set_on_block( true );
                        (*iter0).Set_jumping( false );
                    }

                    if( 'L' == tower1 )
                    {
                        (*iter0).Set_moving_right( false );
                        (*iter0).Jump();
                    }
                    else if( 'T' == tower1 )
                    {
                        (*iter0).Set_on_block( true );
                        (*iter0).Set_jumping( false );
                    }

                    if( 'L' == tower2 )
                    {
                        (*iter0).Set_moving_right( false );
                        (*iter0).Jump();
                    }
                    else if( 'T' == tower2 )
                    {
                        (*iter0).Set_on_block( true );
                        (*iter0).Set_jumping( false );
                    }

                    if( 'R' == tower2 )
                    {
                        (*iter0).Set_moving_right( true );
                        (*iter0).Jump();
                    }
                    iter0++;
                }
                else if( 'D' == ascend_or_descend )
                {
                    (*iter0).Set_on_block( false );

                    if( 'L' == tower0 )
                    {
                        (*iter0).Set_moving_right( false );
                        (*iter0).Jump();
                    }

                    if( 'T' == tower0 )
                    {
                        (*iter0).Set_on_block( true );
                        (*iter0).Set_jumping( false );
                    }
                    else if( 'R' == tower0 )
                    {
                        (*iter0).Set_moving_right( true );
                        (*iter0).Jump();
                    }

                    if( 'T' == tower1 )
                    {
                        (*iter0).Set_on_block( true );
                        (*iter0).Set_jumping( false );
                    }
                    else if( 'R' == tower1 )
                    {
                        (*iter0).Set_moving_right( true );
                        (*iter0).Jump();
                    }

                    if( 'T' == tower2 )
                    {
                        (*iter0).Set_on_block( true );
                        (*iter0).Set_jumping( false );
                    }
                    else if( 'R' == tower2 )
                    {
                        (*iter0).Set_moving_right( true );
                        (*iter0).Jump();
                    }
                    iter0++;
                }
            }
            else
                iter0++;
        }
        else
        {
            SDL_Rect block = rect_location_vector[0];

            //(*(iter0)).Set_moving( true );
            if( (enemy_sprite.x + enemy_sprite.w) >= block.x - 5 && (enemy_sprite.x <= (block.x + block.w + 5) ) )
            {
                char left_right_top_bottom = Left_right_top_bottom_collision( enemy_sprite, block );

                switch( left_right_top_bottom )
                {
                    case 'L':
                        (*iter0).Set_moving_right( false );
                        (*iter0).Jump();
                        break;
                    case 'R':
                        (*iter0).Set_moving_right( true );
                        (*iter0).Jump();
                        break;
                    case 'T':
                        (*iter0).Set_on_block( true );
                        (*iter0).Set_jumping( false );
                        break;
                    default:
                        (*iter0).Set_on_block( false );
                        (*iter0).Set_jumping( false );
                        break;

                }
                iter0++;
            }
            else
                iter0++;
        } // else

    }// while
} // Detect_block_collision( Enemy_control &enemys )

void Block::Detect_bullet_damage( Player &current_player, Enemy_control &enemys, Bullets_control &bullets)
{
    SDL_Rect player_sprite = current_player.Get_sprite_info();
    vector< Enemy >::iterator enemy_iter0 = enemys.Get_enemy_control_begin();
    list< Bullet * >::iterator bullet_iter0 = bullets.Get_bullets_control_begin();

    // get the enemy damage
    int enemy_damage = (*enemy_iter0).Get_damage();

    while( bullet_iter0 != bullets.Get_bullets_control_end() )
    {
        //cout << "im jon the loop\n";
        SDL_Rect bullet_sprite = (*bullet_iter0)->Get_bullet_loc();
        char bullet_id = (*bullet_iter0)->Get_bullet_id();

        if( 'E' == bullet_id )
        {
            char left_right_top_bottom = Left_right_top_bottom_collision( player_sprite, bullet_sprite );

            switch( left_right_top_bottom )
            {
                case 'L':
                    current_player.Take_from_health( enemy_damage );
                    bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );
                    break;
                case 'R':
                    current_player.Take_from_health( enemy_damage );
                    bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );
                    break;
                default:
                    bullet_iter0++;
                    break;
            }
        }
        else if( 'P' == bullet_id )
        {
            bool bullet_taken = false;
            enemy_iter0 = enemys.Get_enemy_control_begin();
            while( enemy_iter0 != enemys.Get_enemy_control_end() )
            {
                //cout << "inside of while loop\n";
                if( false == (*enemy_iter0).Is_dead() )
                {
                    SDL_Rect enemy_sprite = (*enemy_iter0).Get_sprite_info();
                    char left_right_top_bottom = Left_right_top_bottom_collision( enemy_sprite, bullet_sprite );

                    if( 'L' == left_right_top_bottom )
                    {
                        (*(enemy_iter0)).Take_from_health( current_player.Get_damage() );
                        bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );
                        //cout << "damage to enemy!\n";

                        // end this while loop. the nasty way
                        enemy_iter0 = enemys.Get_enemy_control_end();
                        bullet_taken = true;
                    }
                    else if( 'R' == left_right_top_bottom )
                    {
                        (*(enemy_iter0)).Take_from_health( current_player.Get_damage() );
                        bullet_iter0 = bullets.Remove_bullet( bullet_iter0 );
                        //cout << "damage to enemy!\n";

                        // end this while loop. the nasty way
                        enemy_iter0 = enemys.Get_enemy_control_end();
                        bullet_taken = true;
                    }
                    else
                        enemy_iter0++;
                }
                else
                    enemy_iter0++;

            } // while

            if( false == bullet_taken )
                bullet_iter0++;
        }

    } // while

} //Detect_bullet_damage( Player &current_player, Enemy_control &enemys, Bullets_control &bullets)

void Block::Detect_collision( Player &current_player, Enemy_control &enemys, Levels *current_level, Bullets_control &bullets )
{
    if( 0 == block_type.compare( "rockbg" ) )
    {
        // check player collision against the blocks
        Detect_block_collision( current_player, current_level );
//
//        // check enemys collision against the blocks
//        Detect_block_collision( enemys );
    }
    else
    {
        // check player collision against the blocks
        Detect_block_collision( current_player, current_level );

        // check enemys collision against the blocks
        Detect_block_collision( enemys );

       // check bullets collision against the blocks
        Detect_bullet_block_collision( bullets );

        // check to see if the bullets are causing damage
        Detect_bullet_damage( current_player, enemys, bullets);
    }

} // Detect_collision()

void Block::Draw( int bgX3, int bgY)
{
    int index1 = 0,
        index2 = 1;

    int loop_val = 0;
    while( loop_val != rect_location_vector.size() )
    {
        int iter1_x = CONST_X_Y_vector[ index1 ], // X
            iter1_y = CONST_X_Y_vector[ index2 ]; // Y

        rect_location_vector[ loop_val ].x = iter1_x + bgX3;
        rect_location_vector[ loop_val ].y = iter1_y + bgY; // - changed on 18-May-2010

        // nasty code, BUT it works
        if( 0 == block_type.compare( "rockbg" ) )
        {
            block_img.draw( rect_location_vector[ loop_val ].x, rect_location_vector[ loop_val ].y );
            block_img.draw( rect_location_vector[ loop_val ].x + 85, rect_location_vector[ loop_val ].y );
            block_img.draw( rect_location_vector[ loop_val ].x + 170, rect_location_vector[ loop_val ].y );
        }
        else
        {
            block_img.draw( rect_location_vector[ loop_val ].x, rect_location_vector[ loop_val ].y );
        }

        // increase the indexes to move to the next pair of X/Y points
        index1 += 2;
        index2 += 2;
        loop_val++;
    }
} // Draw()

string Block::Get_block_type()
{
    return block_type;
}
